<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 8.5.&nbsp; exit Functions</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch08lev1sec4.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch08lev1sec6.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch08lev1sec5"></a>
<h3 class="docSection1Title" id="454331-805">8.5. <tt>exit</tt> Functions</h3>
<p class="docText">As we described in <a class="docLink" href="ch07lev1sec3.html#ch07lev1sec3">Section 7.3</a>, a process can terminate normally in five ways:</P>
<div style="font-weight:bold"><ol class="docList" type="1"><LI><div style="font-weight:normal"><p class="docList">Executing a <tt>return</tt> from the <tt>main</tt> function. As we saw in <a class="docLink" href="ch07lev1sec3.html#ch07lev1sec3">Section 7.3</a>, this is equivalent to calling <tt>exit</tt>.</p></div></LI><LI><div style="font-weight:normal"><p class="docList">Calling the <tt>exit</tt> function. This function is defined by ISO C and includes the calling of all exit handlers that have been registered by calling <tt>atexit</tt> and closing all standard I/O streams. Because ISO C does not deal with file descriptors, multiple processes (parents and children), and job control, the definition of this function is incomplete for a UNIX system.</P></div></li><LI><div style="font-weight:normal"><p class="docList">Calling the <tt>_exit</tt> or <tt>_Exit</tt> function. ISO C defines <tt>_Exit</tt> to provide a way for a process to terminate without running exit handlers or signal handlers. Whether or not standard I/O streams are flushed depends on the implementation. On UNIX systems, <tt>_Exit</tt> and <tt>_exit</tt> are synonymous and do not flush standard I/O streams. The <tt>_exit</tt> function is called by <tt>exit</tt> and handles the UNIX system-specific details; <tt>_exit</tt> is specified by POSIX.1.</P><blockquote>
<p class="docText">In most UNIX system implementations, <tt>exit</tt>(3) is a function in the standard C library, whereas <tt>_exit</tt>(2) is a system call.</P>
</blockquote></div></li><LI><div style="font-weight:normal"><p class="docList">Executing a <tt>return</tt> from the start routine of the last thread in the process. The return value of the thread is not used as the return value of the process, however. When the last thread returns from its start routine, the process exits with a termination status of 0.</p></div></LI><LI><div style="font-weight:normal"><p class="docList">Calling the <tt>pthread_exit</tt> function from the last thread in the process. As with the previous case, the exit status of the process in this situation is always 0, regardless of the argument passed to <tt>pthread_exit</tt>. We'll say more about <tt>pthread_exit</tt> in <a class="docLink" href="ch11lev1sec5.html#ch11lev1sec5">Section 11.5</a>.</P></div></li></ol></div>
<p class="docText">The three forms of abnormal termination are as follows:</P>
<div style="font-weight:bold"><ol class="docList" type="1"><LI><div style="font-weight:normal"><p class="docList">Calling <tt>abort</tt>. This is a special case of the next item, as it generates the <tt>SIGABRT</tt> signal.</p></div></LI><LI><div style="font-weight:normal"><p class="docList">When the process receives certain signals. (We describe signals in more detail in <a class="docLink" href="ch10.html#ch10">Chapter 10</a>). The signal can be generated by the process itselffor example, by calling the <tt>abort</tt> functionby some other process, or by the kernel. Examples <a name="idd1e54466"></a><a name="idd1e54471"></a><a name="idd1e54476"></a><a name="idd1e54481"></a><a name="idd1e54486"></a><a name="idd1e54491"></a><a name="idd1e54496"></a>of signals generated by the kernel include the process referencing a memory location not within its address space or trying to divide by 0.</p></div></li><li><div style="font-weight:normal"><p class="docList">The last thread responds to a cancellation request. By default, cancellation occurs in a deferred manner: one thread requests that another be canceled, and sometime later, the target thread terminates. We discuss cancellation requests in detail in <a class="docLink" href="ch11lev1sec5.html#ch11lev1sec5">Sections 11.5</a> and <a class="docLink" href="ch12lev1sec7.html#ch12lev1sec7">12.7</a>.</p></div></LI></ol></div>
<p class="docText">Regardless of how a process terminates, the same code in the kernel is eventually executed. This kernel code closes all the open descriptors for the process, releases the memory that it was using, and the like.</p>
<p class="docText">For any of the preceding cases, we want the terminating process to be able to notify its parent how it terminated. For the three exit functions (<tt>exit</tt>, <tt>_exit</tt>, and <tt>_Exit</tt>), this is done by passing an exit status as the argument to the function. In the case of an abnormal termination, however, the kernel, not the process, generates a termination status to indicate the reason for the abnormal termination. In any case, the parent of the process can obtain the termination status from either the <tt>wait</tt> or the <tt>waitpid</tt> function (described in the next section).</P>
<p class="docText">Note that we differentiate between the exit status, which is the argument to one of the three exit functions or the return value from <tt>main</tt>, and the termination status. The exit status is converted into a termination status by the kernel when <tt>_exit</tt> is finally called (recall <a class="docLink" href="ch07lev1sec3.html#ch07fig02">Figure 7.2</a>). <a class="docLink" href="#ch08fig04">Figure 8.4</a> describes the various ways the parent can examine the termination status of a child. If the child terminated normally, the parent can obtain the exit status of the child.</p>
<a name="ch08fig04"></a><P><table cellspacing="0" class="allBorders" border="1" RULES="all" cellpadding="4"><caption><h5 class="docTableTitle">Figure 8.4. Macros to examine the termination status returned by <tt>wait</tt> and <tt>waitpid</tt></h5></caption><colgroup><col width="125"><col width="375"></colgroup><thead><tr><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Macro</span></p></th><th class="thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Description</span></p></th></tr></thead><tr><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>WIFEXITED</tt>(<span class="docEmphasis">status</span>)</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">True if status was returned for a child that terminated normally. In this case, we can execute</p>
<blockquote><p><p class="docList"><tt>WEXITSTATUS</tt> (<span class="docEmphasis">status</span>)</p></p></blockquote>
<p class="docText">to fetch the low-order 8 bits of the argument that the child passed to <tt>exit</tt>, <tt>_exit</tt>,or <tt>_Exit</tt>.</p></td></TR><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>WIFSIGNALED</tt> (<span class="docEmphasis">status</span>)</P></TD><TD class="docTableCell" align="left" valign="top"><p class="docText">True if status was returned for a child that terminated abnormally, by receipt of a signal that it didn't catch. In this case, we can execute</p>
<blockquote><P><p class="docList"><tt>WTERMSIG</tt> (<span class="docEmphasis">status</span>)</P></P></blockquote>
<p class="docText">to fetch the signal number that caused the termination.</p>
<p class="docText">Additionally, some implementations (but not the Single UNIX Specification) define the macro</P>
<blockquote><p><p class="docList"><tt>WCOREDUMP</tt> (<span class="docEmphasis">status</span>)</P></P></blockquote>
<p class="docText">that returns true if a core file of the terminated process was generated.</P></td></TR><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>WIFSTOPPED</tt> (<span class="docEmphasis">status</span>)</P></TD><td class="docTableCell" align="left" valign="top"><p class="docText">True if status was returned for a child that is currently stopped. In this case, we can execute</p>
<blockquote><p><p class="docList"><tt>WSTOPSIG</tt> (<span class="docEmphasis">status</span>)</p></P></blockquote>
<p class="docText">to fetch the signal number that caused the child to stop.</p></TD></tr><TR><td class="docTableCell" align="left" valign="top"><p class="docText"><tt>WIFCONTINUED</tt> (<span class="docEmphasis">status</span>)</p></td><td class="docTableCell" align="left" valign="top"><p class="docText">True if status was returned for a child that has been continued after a job control stop (XSI extension to POSIX.1; <tt>waitpid</tt> only).</p></td></tr></table></p><br>
<p class="docText">When we described the <tt>fork</tt> function, it was obvious that the child has a parent process after the call to <tt>fork</tt>. Now we're talking about returning a termination status to the parent. But what happens if the parent terminates before the child? The answer is that the <tt>init</tt> process becomes the parent process of any process whose parent terminates. We say that the process has been inherited by <tt>init</tt>. What normally happens is that whenever a process terminates, the kernel goes through all active processes to see whether the terminating process is the parent of any process that still exists. If so, the parent process ID of the surviving process is changed to be 1 (the process ID of <tt>init</tt>). This way, we're guaranteed that every process has a parent.</p>
<p class="docText">Another condition we have to worry about is when a child terminates before its parent. If the child completely disappeared, the parent wouldn't be able to fetch its termination status when and if the parent were finally ready to check if the child had terminated. The kernel keeps a small amount of information for every terminating process, so that the information is available when the parent of the terminating process calls <tt>wait</tt> or <tt>waitpid</tt>. Minimally, this information consists of the process ID, the termination status of the process, and the amount of CPU time taken by the process. The kernel can discard all the memory used by the process and close its open files. In UNIX System terminology, a process that has terminated, but whose parent has not yet waited for it, is called a <span class="docEmphasis">zombie</span>. The <tt>ps</tt>(1) command prints the state of a zombie process as <span class="docEmphasis">Z</span>. If we write a long-running program that <tt>fork</tt>s many child processes, they become zombies unless we wait for them and fetch their termination status.</p>
<blockquote>
<p class="docText">Some systems provide ways to prevent the creation of zombies, as we describe in <a class="docLink" href="ch10lev1sec7.html#ch10lev1sec7">Section 10.7</a>.</p>
</blockquote>
<p class="docText"><a name="idd1e54784"></a><a name="idd1e54789"></a><a name="idd1e54794"></a><a name="idd1e54801"></a>The final condition to consider is this: what happens when a process that has been inherited by <tt>init</tt> terminates? Does it become a zombie? The answer is &quot;no,&quot; because <tt>init</tt> is written so that whenever one of its children terminates, <tt>init</tt> calls one of the <tt>wait</tt> functions to fetch the termination status. By doing this, <tt>init</tt> prevents the system from being clogged by zombies. When we say &quot;one of <tt>init</tt>'s children,&quot; we mean either a process that <tt>init</tt> generates directly (such as <tt>getty</tt>, which we describe in <a class="docLink" href="ch09lev1sec2.html#ch09lev1sec2">Section 9.2</a>) or a process whose parent has terminated and has been subsequently inherited by <tt>init</tt>.</p>

<ul></ul></td></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch08lev1sec4.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch08lev1sec6.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--87-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--87-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
